/* asciiboard.h - Copyright (C) 2014 James Boyle

   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>. */
#ifndef ASCIIBOARD_HEADER_INCLUDED
#define ASCIIBOARD_HEADER_INCLUDED

#include "asciiboard_const.h"

/* global defines */
#define FLOAT_BUFFER_SIZE 32 /* to store single precision float as string */
#ifndef M_PI
#define M_PI (3.1415926535897932f)
#endif
#define TWOPI (2.0f * M_PI)

/* defines for processing functions */
#define VIBRATO_FREQ 6.0f
#define VIBRATO_AMOUNT 0.04f
#define VIBRATO_DELAY 4
#define MAX_HARMONIC 8
#define TREMOLO_FREQ 3.0f
#define TREMOLO_AMOUNT 0.8f
#define DECAY_SAMPLE_COUNT 2
#define DECAY_INCR ((WAVE_SIZE - 1.0f) / (DECAY_SAMPLE_COUNT * PERIOD_SAMPLES))
#define LOOKAHEAD_TIME 0.003f

/* ascii_through_release() */
#define EXP_DECAY_CODE 'E'
#define LINEAR_DECAY_CODE 'L'
/* ascii_tremolo() */
#define TREMOLO_CODE 'B'
/*ascii_vibrato() */
#define VIBRATO_CODE 'V'
/* ascii_waveform() */
#define SQUARE_CODE 'Q'
#define TRIANGLE_CODE 'T'
#define SAW_CODE 'W'
#define NOISE_CODE 'N'
#define WAVEFORM_TOGGLE_CHANNEL_CODE '@'
/* ascii_sustain() */
#define SUSTAIN_CODE 'U'

/* ascii_through_release() */
typedef enum tone_state { TONE_NOT_ACTIVE, TONE_ACTIVE, TONE_RELEASE }
TONE_STATE;
typedef enum release_mode { LINEAR_DECAY, EXP_DECAY } RELEASE_MODE;

extern const float default_tone_map[];
extern const float default_wave[];

/* functions required to use and configure the engine in a program */
void asciiboard_init(void (*sf)(const char), float *out_buffer,
                     const int buffer_size,
                     void (*af)(const float *, const int, void *),
                     void *af_args,
					 int (*tf)(void));
void asciiboard_finish(void);
int asciiboard(const char);
void asciiboard_set_audio_buffer(float *const new_buffer, const int buffer_size);

/* functions useful for debugging the library */
void asciiboard_error(const int error);
void asciiboard_stress_test(const int max_iterations);
void asciiboard_benchmark(const int iterations);
void asciiboard_tone_debug(void);

/* functions to help interface with the ASCIIBoard engine, allowing you to
   write your own text processing functions more easily */
const int convert_char_to_tone(const char ch);
const int is_tone_code(const char tone_code);
int streaming_data(void);
int envelopes_synced(void);
int sounding_tone_count(void);
void transmit_ch(const char ch);
int set_wave_table(const float *wave, const int size, const int chan);
int set_envelope_pts(const float *envelope, const int size, const int chan);
int set_tone_map(const float *map, const int size, const int chan);
int asciiboard_add_processing_func(int (*f)(const char), const int priority);

const float *read_wave_table(const int chan);
const float *read_envelope(const int chan, int *size);
const float *read_tone_map(const int chan);

/* a set of example text processing functions */
/* default */
int ascii_through(const char ch);
/* throughput functions that ignore comments or demonstrate sustain and
   release */
int ascii_through_comments(const char ch);
int ascii_through_sustain(const char ch);
int ascii_through_release(const char ch);
/* common synthesiser features */
int ascii_vibrato(const char ch);
int ascii_tremolo(const char ch);
/* common waveform generation */
int ascii_common_waveform(const char ch);

/* a set of useful tone managing functions, to achieve more complex control
   over the synth */
int sustain(const char ch, int tones_to_transmit[TONE_COUNT]);
int tone_release(const char ch, int tones_to_transmit[TONE_COUNT]);

/* a set of useful waveform / envelope / tone map generating functions, which
  may be called at any point in a program */
void square_gen(float *square, const int max_harmonic, const int size);
void triangle_gen(float *triangle, const int max_harmonic, const int size);
void saw_gen(float *saw, const int max_harmonic, const int size);
void ramp_gen(float *ramp, const float initial, const float end,
              const int size);
void exp_gen(float *exp, const float initial, const float decay_rate,
             const int size);
void noise_gen(float *noise, const int size);

/* a set of useful DSP functions, to apply to the output audio, note that
   the output of these functions can't be recorded via the save feature */
void amplify(float *const samples, const float amp, const int count);
void normalise(float *const samples, const float norm, const int count);
void low_pass(const float *const read, float *write, const float cut_off,
              const int count);

#endif
